<!--
 * @Author: Dorange.Wang
 * @Date: 2021-04-07 14:14:53
 * @LastEditors: your name
 * @LastEditTime: 2021-11-19 17:41:47
 * @Description: file content
-->
<route>
{
  "meta":{
    "title": "人员管理",
    "localism": "sys.personnel_management"
  }
}
</route>
<template>
  <el-row class="pt20" v-loading="loading">
    <el-col class="user-avatar" :span="6">
      <el-avatar
        style="background-color: #fff"
        :size="160" :src="formData.avatar||defaultAvatar">
      </el-avatar>
      <common-upload
        base64
        :size="0.5"
        :beforeUpload="beforeUpload"
        @success="handleUploadSuccess"
      >
        <el-button icon="el-icon-upload2">{{$t('sys.change_avatar')}}</el-button>
      </common-upload>
      <div
        style="
          font-size: 12px;
          color: #999;
          width: 75%;
          line-height: 1.5;
          margin-top: 10px;
        "
      >
        {{$t('sys.avatar_picture_rule')}}
      </div>
    </el-col>
    <el-col :span="12">
      <el-form
        :model="formData"
        ref="form"
        label-width="120px"
        label-position="right"
      >
        <el-form-item
          :label="$t('sys.name')"
          prop="name"
          :rules="[
            { required: true, message: $t('sys.name_not_null'), trigger: 'change' }
          ]"
        >
          <el-input
            style="width: 500px"
            v-model="formData.name"
            :placeholder="$t('sys.enter_name')"
            :maxlength="64"
            show-word-limit
          />
        </el-form-item>

        <el-form-item
          :label="$t('sys.gender')"
          prop="gender"
          :rules="[
            { required: true, message: $t('sys.select_gender'), trigger: 'change' }
          ]"
        >
          <el-radio-group v-model="formData.gender">
            <el-radio
              v-for="item in GENDER_ENUM"
              :key="item.key"
              :label="item.key"
            >{{ $t('sys.' + item.i18nLable) }}</el-radio
            >
          </el-radio-group>
        </el-form-item>

        <el-form-item
          :label="$t('sys.account_number')"
          prop="username"
          :rules="[
            { required: true, message: $t('sys.account_number_not_null'), trigger: 'change' }
          ]"
        >
          <el-input
            style="width: 500px"
            v-model="formData.username"
            :placeholder="$t('sys.enter_account_number')"
            :maxlength="64"
            show-word-limit
          />
        </el-form-item>
        <el-form-item
          v-if="isNew"
          :label="$t('sys.password')"
          prop="password"
          :rules="[
            { required: true, message: $t('sys.password_not_null'), trigger: 'change' },
            {
              pattern: pwdCheck ? PASSWORD_COMPLEX_REG : PASSWORD_REG,
              message: $t('sys.enter_valid_password'),
              trigger: 'change'
            }
          ]"
        >
          <template
            slot="label"
          >{{$t('sys.password')}}
            <el-tooltip popper-class="custom-popper" placement="top">
              <div slot="content">
                <div>{{ $t('sys.' + (pwdCheck ? PASSWORD_COMPLEX_REG_MSG_I18N : PASSWORD_REG_MSG_I18N)) }}</div>
                <div class="mt5">{{$t('sys.default_password')}}</div>
              </div>
              <i class="el-icon-question" />
            </el-tooltip>
          </template>
          <div style="width: 500px; display: flex">
            <el-input
              autocomplete="new-password"
              v-model="formData.password"
              :placeholder="$t('sys.enter_password')"
              :maxlength="32"
              show-word-limit
              show-password
            />
            <el-button
              style="margin-left: 10px"
              type="text"
              @click="handleRandom"
            >{{$t('sys.random_password')}}</el-button
            >
          </div>
        </el-form-item>

        <el-form-item v-else :label="$t('sys.password')">
          <el-button type="text" @click="handleResetPwd">{{$t('sys.reset_password')}}</el-button>
        </el-form-item>

        <el-divider />

        <el-form-item
          :label="$t('sys.department')"
          prop="orgIds"
          :rules="[
            { required: true, message: $t('sys.select_belong_to_department'), trigger: 'change' }
          ]"
        >
          <div style="min-height: 30px; width: 500px">
            <el-tag
              style="margin-right: 10px"
              size="medium"
              v-for="item in formData.orgList"
              :key="item.id"
              :closable="item.id !== formData.orgId"
              type="info"
              @close="handleOrgDelete(item)"
            >
              <span
                class="tag-content-main"
                v-if="item.id === formData.orgId"
              >{{$t('sys.main')}}</span
              >
              {{ item.name }}
            </el-tag>
            <el-button type="text" @click="handleOrgSelect">{{$t('sys.modify')}}</el-button>
          </div>
        </el-form-item>

        <el-form-item :label="$t('sys.post')" prop="position">
          <el-input
            style="width: 500px"
            v-model="formData.position"
            :placeholder="$t('sys.enter_post')"
            :maxlength="128"
            show-word-limit
          />
        </el-form-item>

        <el-form-item
          :label="$t('sys.identity')"
          prop="identityType"
          :rules="[
            { required: true, message: $t('sys.select_identity'), trigger: 'change' }
          ]"
        >
          <el-radio-group v-model="formData.identityType">
            <el-radio
              v-for="(value, key) in IDENTITY_TYPE_ENUM"
              :key="key"
              :label="key"
            >{{ $t('sys.' +value) }}</el-radio
            >
          </el-radio-group>
        </el-form-item>

        <el-form-item
          v-if="formData.identityType === 'HIGHER'"
          :label="$t('sys.responsible_department')"
          prop="manageOrg"
          :rules="[
            {
              required: formData.identityType === 'HIGHER',
              message: $t('sys.select_responsible_department'),
              trigger: 'change'
            }
          ]"
        >
          <el-select
            v-model="formData.manageOrg"
            multiple
            filterable
            style="width: 500px"
            :placeholder="$t('sys.select_responsible_department')"
            @change="handleManageOrgChange"
          >
            <el-option
              v-for="item in formData.orgList"
              :key="item.id"
              :value="item.id"
              :label="item.name"
            />
          </el-select>
        </el-form-item>

        <el-form-item label="" v-if="formData.identityType === 'HIGHER' && manageOrgWarningList.length > 0">
          <div
            class="manage-org--warning"
            v-for="item in manageOrgWarningList"
            :key="item.orgId"
          >
            <i class="el-icon-warning mr5"></i>
            {{ item.warning.message }}
          </div>
        </el-form-item>

        <el-form-item :label="$t('sys.direct_superior')" prop="higherId">
          <el-tag
            v-if="formData.higherId"
            style="margin-right: 10px"
            size="medium"
            type="info"
            closable
            @close="handleHigherDelete"
          >{{ formData.higherName }}</el-tag
          >
          <el-button type="text" @click="handleHigherSelect">{{
            formData.higherId ? $t('sys.modify') : $t('sys.select_superior')
          }}</el-button>
        </el-form-item>

        <el-divider />

        <el-form-item :label="$t('sys.job_number')" prop="jobNumber">
          <el-input
            style="width: 500px"
            v-model="formData.jobNumber"
            :placeholder="$t('sys.enter_job_number')"
            :maxlength="32"
            show-word-limit
          />
        </el-form-item>

        <el-form-item :label="$t('sys.english_name')" prop="englishName">
          <el-input
            style="width: 500px"
            v-model="formData.englishName"
            :placeholder="$t('sys.enter_english_name')"
            :maxlength="64"
            show-word-limit
          />
        </el-form-item>

        <el-form-item
          :label="$t('sys.cellphone_number')"
          prop="mobile"
          :rules="[
            { validator: mobileEmailValidator, trigger: 'change' },
            {
              pattern: MOBILE_REG,
              message: $t('sys.enter_valid_cellphone_number'),
              trigger: 'change'
            }
          ]"
        >
          <el-input
            style="width: 500px"
            v-model="formData.mobile"
            :placeholder="$t('sys.enter_cellphone_number')"
            :maxlength="11"
            show-word-limit
          >
            <el-select
              style="width: 80px"
              v-model="formData.phoneRegion"
              slot="prepend"
            >
              <el-option
                v-for="item in PHONE_REGION_ENUM"
                :label="item.value"
                :key="item.key"
                :value="item.key"
              ></el-option>
            </el-select>
          </el-input>
        </el-form-item>

        <el-form-item :label="$t('sys.landline')" prop="telephone">
          <el-input
            style="width: 500px"
            v-model="formData.telephone"
            :placeholder="$t('sys.enter_landline')"
            :maxlength="32"
            show-word-limit
          />
        </el-form-item>

        <el-form-item
          :label="$t('sys.email')"
          prop="email"
          :rules="[
            { validator: mobileEmailValidator, trigger: 'change' },
            { type: 'email', message: $t('sys.enter_valid_email'), trigger: 'change' }
          ]"
        >
          <el-input
            style="width: 500px"
            v-model="formData.email"
            :placeholder="$t('sys.enter_email')"
            :maxlength="128"
            show-word-limit
          />
        </el-form-item>

        <el-divider />

        <el-form-item :label="$t('sys.hid_card_number')">
          <el-input
            style="width: 500px"
            type="textarea"
            v-model="formData.hidNo"
            :placeholder="$t('sys.enter_hid_card_number')"
            :maxlength="500"
            show-word-limit
          />
        </el-form-item>

        <el-form-item>
          <el-button type="primary" :loading="loading" @click="submit">{{$t('sys.confirm')}}</el-button>
        </el-form-item>
      </el-form>
    </el-col>

    <select-org-modal
      :title="$t('sys.select_department')"
      ref="SelectOrgModal"
      :treeData="orgTree"
      showCheckbox
      @ok="handleSelectOrgOk"
    />

    <select-modal
      itemRadio
      :title="$t('sys.select_superior')"
      :autoClose="false"
      ref="SelectHigherModal"
      :treeData="orgTree"
      :disabledNodeKeys="disabledNodeKeys"
      :treeNodeChange="handleSelectHigherNodeChange"
      @ok="handleHigherChange"
    >
      <template v-slot:item="slotProps">
        {{ [slotProps.data.jobNumber, slotProps.data.name] | user }}
      </template>
    </select-modal>
  </el-row>
</template>

<script>
import md5 from 'md5'
import { arrayToTree, randomString,randomStringStrong } from '@/utils/util'
// import { baseURL } from '@/config/api.config'
import {
  GENDER_ENUM,
  PHONE_REGION_ENUM,
  IDENTITY_TYPE_ENUM
} from '@/utils/enum'
import { MOBILE_REG, PASSWORD_REG, PASSWORD_REG_MSG, PASSWORD_REG_MSG_I18N,PASSWORD_COMPLEX_REG,PASSWORD_COMPLEX_REG_MSG_I18N } from '@/utils/reg'

import { getHmorgListwithpermission } from '@/apis/paas/HmOrgController.js'
import { getHmuserInfo, postHmuser, putHmuser, getHmuserPageListwithpermission, putHmuserUpdatepwd, getHmuserCheckOrgmanageExist } from '@/apis/paas/HmUserController.js'
import SelectOrgModal from './__components__/SelectOrgModal'
import SelectModal from '@/components/SelectModal'
import ResetPassword from '@/components/ResetPassword'
import defaultAvatar from '@/assets/image/defaultAvatar.png'
import { mapGetters } from "vuex"

const defaultFormData = {
  gender: GENDER_ENUM[0].key,
  phoneRegion: PHONE_REGION_ENUM[0].key,
  identityType: Object.keys(IDENTITY_TYPE_ENUM)[0],
  orgList: [],
  manageOrg: [],
  password: '111111'
}

export default {
  name: 'User',
  components: {
    SelectOrgModal,
    SelectModal
  },
  data () {
    return {
      defaultAvatar,
      loading: false,
      GENDER_ENUM,
      PHONE_REGION_ENUM,
      IDENTITY_TYPE_ENUM,
      MOBILE_REG,
      PASSWORD_REG,
      PASSWORD_REG_MSG,
      PASSWORD_REG_MSG_I18N,
      PASSWORD_COMPLEX_REG,
      PASSWORD_COMPLEX_REG_MSG_I18N,
      formData: {
        ...defaultFormData
      },
      orgList: [],
      orgTree: [],
      disabledNodeKeys: [],
      manageOrgOldValue: [],
      manageOrgWarningList: []
    }
  },

  computed: {
    ...mapGetters(["APP_INFO"]),
    isNew () {
      return !this.formData.id
    },
    pwdCheck () {
      return this.APP_INFO.pwdCheck || false;
    }

    // avatar () {
    //   const { avatar } = this.formData
    //   return avatar ? baseURL + avatar : ''
    // }
  },

  created () {
    const { org, id } = this.$route.query
    this._userId = Number(id)
    this._orgId = Number(org)

    this._userId && this.loadUserData()
    this.loadOrgData()
  },

  watch: {
    '$route.query.id' (value) {
      this._userId = Number(value)
      this.loadUserData()
    },
    'formData.mobile' (val) {
      this.$refs.form.validateField('email')
    },
    'formData.email' (val) {
      this.$refs.form.validateField('mobile')
    }
  },

  methods: {
    mobileEmailValidator (rule, value, callback) {
      const { mobile, email } = this.formData
      if (!mobile && !email) {
        callback(new Error(this.$t('sys.cellphone_number_email_must_be_one')))
      } else {
        callback()
      }
    },

    loadUserData () {
      this.loading = true
      this.$set(this.formData, 'id', this._userId)
      getHmuserInfo({
        id: this._userId
      })
        .then((res) => {
          this.formData = {
            ...res,
            orgIds: res.orgList.map((item) => item.id),
            manageOrg: res.manageOrg
              ? res.manageOrg
                .split(/[\\[|\]]/)
                .filter((item) => item)
                .map(Number)
              : defaultFormData.manageOrg
          }
        })
        .finally(() => {
          this.loading = false
        })
    },

    loadOrgData () {
      getHmorgListwithpermission().then((res) => {
        this.orgList = res.map((i) => {
          return {
            ...i,
            disabled: i.accessLevel === 'ReadOnly'
          }
        })
        this.disabledNodeKeys = this.orgList
          .filter((i) => i.accessLevel === 'ReadOnly')
          .map((i) => i.id)
        this.orgTree = arrayToTree(this.orgList)
        // 获取新建时org信息、用于选择部门组件
        if (this._orgId) {
          const orgList = res.find((item) => item.id === this._orgId)
          if (orgList) {
            this.$set(this.formData, 'orgId', this._orgId)
            this.$set(this.formData, 'orgIds', [this._orgId])
            this.$set(this.formData, 'orgList', [orgList])
          }
        }
      })
    },

    beforeUpload (file) {
      const type = file.name.split('.').pop().toLowerCase()
      if (['jpg', 'png'].includes(type)) {
        return true
      } else {
        this.$message.error(this.$t('sys.only_upload_JPG _PNG_format'))
        return false
      }
    },

    handleUploadSuccess (data) {
      this.$set(this.formData, 'avatar', data)
    },

    handleOrgSelect () {
      const options = {
        nodeCheckedData: this.formData.orgList,
        nodeSelected: this.formData.orgId
      }
      this.$refs.SelectOrgModal.open(options)
    },

    handleOrgDelete (item) {
      const orgList = this.formData.orgList.filter((org) => org.id !== item.id)
      this.$set(
        this.formData,
        'orgIds',
        orgList.map((org) => org.id)
      )
      this.$set(this.formData, 'orgList', orgList)

      // 需要同步更新负责部门
      const manageOrg = this.formData.manageOrg.filter(
        (orgid) => orgid !== item.id
      )
      this.$set(this.formData, 'manageOrg', manageOrg)
    },

    handleSelectOrgOk (data) {
      const { nodeCheckedData, nodeSelected } = data
      this.$set(this.formData, 'orgId', nodeSelected)
      this.$set(
        this.formData,
        'orgIds',
        nodeCheckedData.map((item) => item.id)
      )
      this.$set(this.formData, 'orgList', nodeCheckedData)
    },

    handleHigherSelect () {
      this.$refs.SelectHigherModal.open()
    },

    handleHigherDelete () {
      this.$set(this.formData, 'higherId', undefined)
      this.$set(this.formData, 'higherName', undefined)
    },

    handleHigherChange (data) {
      const { item } = data
      if (item.length === 0) {
        this.$message.warning(this.$t('sys.select_immediate_superior'))
        return
      }
      const { id, name } = item[0]
      this.$set(this.formData, 'higherId', id)
      this.$set(this.formData, 'higherName', name)
      this.$refs.SelectHigherModal.close()
    },

    handleSelectHigherNodeChange (org) {
      return getHmuserPageListwithpermission({
        pageSize: 100000,
        pageNo: 1,
        orgIds: org.id,
        status: 1
      }).then((res) => {
        return res.data.map((item) => ({
          ...item,
          disabled: item.id === this._userId
        }))
      })
    },

    handleRandom () {
      if(this.pwdCheck){
        this.formData.password = randomStringStrong(6)
      }else{
        this.formData.password = randomString(6)
      }
    },

    handleResetPwd () {
      ResetPassword.open(null, (val) => {
        putHmuserUpdatepwd({
          id: this.formData.id,
          password: val
        }).then(() => {
          this.$message.success(this.$t('sys.operation_success'))
        })
      })
    },

    async handleManageOrgChange (value = []) {
      let addOrgIds
      let delOrgIds
      if (value) {
        addOrgIds = value.filter(item => !this.manageOrgOldValue.includes(item))
        delOrgIds = this.manageOrgOldValue.filter(item => !value.includes(item))
      }
      this.manageOrgOldValue = value
      addOrgIds.forEach(async addOrgId => {
        try {
          await getHmuserCheckOrgmanageExist({
            orgId: addOrgId,
            userId: this.formData.id
          },{
            nomsg: true
          }
          )
        } catch (err) {
          this.manageOrgWarningList.push({
            orgId: addOrgId,
            warning: err
          })
        }
      })
      this.manageOrgWarningList = this.manageOrgWarningList.filter(item => !delOrgIds.includes(item.orgId))
    },

    async submit () {
      try {
        await this.$refs.form.validate()
        const {
          id,
          avatar,
          name,
          gender,
          username,
          password,
          orgId,
          orgIds,
          position,
          identityType,
          manageOrg,
          higherId,
          jobNumber,
          englishName,
          phoneRegion,
          mobile,
          telephone,
          email,
          hidNo
        } = this.formData
        const params = {
          avatar,
          name,
          gender,
          username,
          orgId,
          orgIds,
          position,
          identityType,
          manageOrg:
            identityType === 'HIGHER'
              ? manageOrg.map((item) => `[${item}]`).join('')
              : '',
          higherId,
          jobNumber,
          englishName,
          phoneRegion,
          mobile,
          telephone,
          email,
          hidNo
        }
        let request = null
        if (this.isNew) {
          params.password = md5(password)
          request = postHmuser
        } else {
          params.id = id
          request = putHmuser
        }
        for (const key in params) {
          params[key] =
            typeof params[key] === 'string' ? params[key].trim() : params[key]
        }
        this.loading = true
        request(params)
          .then((res) => {
          this.$message.success(this.$t('sys.operation_success'))
            // this.formData = {
            //   ...defaultFormData
            // }
            // this.$nextTick(() => {
            //   this.$refs.form.clearValidate()
            // })
            if (this.isNew && res) {
              this.$router.replace({
                path: '/organizationPermission/organization/user',
                query: {
                  id: res
                }
              })
            }
          })
          .finally(() => {
            this.loading = false
          })
      } catch (error) {
        console.log(error)
      }
    }
  }
}
</script>

<style lang="scss" scoped>
.user-avatar {
  display: flex;
  flex-direction: column;
  align-items: center;
  .el-avatar {
    margin-bottom: 20px;
  }
}

.tag-content-main {
  color: #1890ff;
  font-weight: bold;
  &::after {
    content: '';
    margin: 0 6px 0 8px;
    display: inline-block;
    width: 1px;
    height: 10px;
    background: #ccc;
    position: relative;
    top: 1px;
  }
}

.manage-org--warning{
  color: #e6a23c;
  width: 500px;
  background: #fdf6ec;
  border-radius: 5px;
  padding: 0 10px;
  box-sizing: border-box;

  &:nth-child(n+2){
    margin-top: 8px;
  }
}
</style>
